// Copyright 2017-2018 Intel Corporation.

#include "tile/hal/opencl/ocl.h"

#include "base/util/logging.h"

namespace vertexai {
namespace tile {
namespace hal {
namespace opencl {

Err::Err(cl_int code) : code_{code} {
  if (code) {
    VLOG(3) << "OpenCL error: " << str() << " (" << code << ")";
  }
}

#define ERR_STR(__code__) \
  case __code__:          \
    return #__code__;

const char* Err::str() const {
  switch (code_) {
    // run-time and JIT compiler errors
    ERR_STR(CL_SUCCESS)
    ERR_STR(CL_DEVICE_NOT_FOUND)
    ERR_STR(CL_DEVICE_NOT_AVAILABLE)
    ERR_STR(CL_COMPILER_NOT_AVAILABLE)
    ERR_STR(CL_MEM_OBJECT_ALLOCATION_FAILURE)
    ERR_STR(CL_OUT_OF_RESOURCES)
    ERR_STR(CL_OUT_OF_HOST_MEMORY)
    ERR_STR(CL_PROFILING_INFO_NOT_AVAILABLE)
    ERR_STR(CL_MEM_COPY_OVERLAP)
    ERR_STR(CL_IMAGE_FORMAT_MISMATCH)
    ERR_STR(CL_IMAGE_FORMAT_NOT_SUPPORTED)
    ERR_STR(CL_BUILD_PROGRAM_FAILURE)
    ERR_STR(CL_MAP_FAILURE)
    ERR_STR(CL_MISALIGNED_SUB_BUFFER_OFFSET)
    ERR_STR(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST)
    ERR_STR(CL_COMPILE_PROGRAM_FAILURE)
    ERR_STR(CL_LINKER_NOT_AVAILABLE)
    ERR_STR(CL_LINK_PROGRAM_FAILURE)
    ERR_STR(CL_DEVICE_PARTITION_FAILED)
    ERR_STR(CL_KERNEL_ARG_INFO_NOT_AVAILABLE)
    ERR_STR(CL_INVALID_VALUE)
    ERR_STR(CL_INVALID_DEVICE_TYPE)
    ERR_STR(CL_INVALID_PLATFORM)
    ERR_STR(CL_INVALID_DEVICE)
    ERR_STR(CL_INVALID_CONTEXT)
    ERR_STR(CL_INVALID_QUEUE_PROPERTIES)
    ERR_STR(CL_INVALID_COMMAND_QUEUE)
    ERR_STR(CL_INVALID_HOST_PTR)
    ERR_STR(CL_INVALID_MEM_OBJECT)
    ERR_STR(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR)
    ERR_STR(CL_INVALID_IMAGE_SIZE)
    ERR_STR(CL_INVALID_SAMPLER)
    ERR_STR(CL_INVALID_BINARY)
    ERR_STR(CL_INVALID_BUILD_OPTIONS)
    ERR_STR(CL_INVALID_PROGRAM)
    ERR_STR(CL_INVALID_PROGRAM_EXECUTABLE)
    ERR_STR(CL_INVALID_KERNEL_NAME)
    ERR_STR(CL_INVALID_KERNEL_DEFINITION)
    ERR_STR(CL_INVALID_KERNEL)
    ERR_STR(CL_INVALID_ARG_INDEX)
    ERR_STR(CL_INVALID_ARG_VALUE)
    ERR_STR(CL_INVALID_ARG_SIZE)
    ERR_STR(CL_INVALID_KERNEL_ARGS)
    ERR_STR(CL_INVALID_WORK_DIMENSION)
    ERR_STR(CL_INVALID_WORK_GROUP_SIZE)
    ERR_STR(CL_INVALID_WORK_ITEM_SIZE)
    ERR_STR(CL_INVALID_GLOBAL_OFFSET)
    ERR_STR(CL_INVALID_EVENT_WAIT_LIST)
    ERR_STR(CL_INVALID_EVENT)
    ERR_STR(CL_INVALID_OPERATION)
    ERR_STR(CL_INVALID_GL_OBJECT)
    ERR_STR(CL_INVALID_BUFFER_SIZE)
    ERR_STR(CL_INVALID_MIP_LEVEL)
    ERR_STR(CL_INVALID_GLOBAL_WORK_SIZE)
    ERR_STR(CL_INVALID_PROPERTY)
    ERR_STR(CL_INVALID_IMAGE_DESCRIPTOR)
    ERR_STR(CL_INVALID_COMPILER_OPTIONS)
    ERR_STR(CL_INVALID_LINKER_OPTIONS)
    ERR_STR(CL_INVALID_DEVICE_PARTITION_COUNT)
#if defined(CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR)
    ERR_STR(CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR)
#endif
#if defined(CL_PLATFORM_NOT_FOUND_KHR)
    ERR_STR(CL_PLATFORM_NOT_FOUND_KHR)
#endif
#if defined(CL_INVALID_D3D10_DEVICE_KHR)
    ERR_STR(CL_INVALID_D3D10_DEVICE_KHR)
#endif
#if defined(CL_INVALID_D3D10_RESOURCE_KHR)
    ERR_STR(CL_INVALID_D3D10_RESOURCE_KHR)
#endif
#if defined(CL_D3D10_RESOURCE_ALREADY_ACQUIRED_KHR)
    ERR_STR(CL_D3D10_RESOURCE_ALREADY_ACQUIRED_KHR)
#endif
#if defined(CL_D3D10_RESOURCE_NOT_ACQUIRED_KHR)
    ERR_STR(CL_D3D10_RESOURCE_NOT_ACQUIRED_KHR)
#endif
    default:
      return "Unknown OpenCL error";
  }
}

const char* EventCommandTypeStr(cl_command_type code) {
  switch (code) {
    ERR_STR(CL_COMMAND_NDRANGE_KERNEL)
    ERR_STR(CL_COMMAND_TASK)
    ERR_STR(CL_COMMAND_NATIVE_KERNEL)
    ERR_STR(CL_COMMAND_READ_BUFFER)
    ERR_STR(CL_COMMAND_WRITE_BUFFER)
    ERR_STR(CL_COMMAND_COPY_BUFFER)
    ERR_STR(CL_COMMAND_READ_IMAGE)
    ERR_STR(CL_COMMAND_WRITE_IMAGE)
    ERR_STR(CL_COMMAND_COPY_IMAGE)
    ERR_STR(CL_COMMAND_COPY_IMAGE_TO_BUFFER)
    ERR_STR(CL_COMMAND_COPY_BUFFER_TO_IMAGE)
    ERR_STR(CL_COMMAND_MAP_BUFFER)
    ERR_STR(CL_COMMAND_MAP_IMAGE)
    ERR_STR(CL_COMMAND_UNMAP_MEM_OBJECT)
    ERR_STR(CL_COMMAND_MARKER)
    ERR_STR(CL_COMMAND_ACQUIRE_GL_OBJECTS)
    ERR_STR(CL_COMMAND_RELEASE_GL_OBJECTS)
    ERR_STR(CL_COMMAND_READ_BUFFER_RECT)
    ERR_STR(CL_COMMAND_WRITE_BUFFER_RECT)
    ERR_STR(CL_COMMAND_COPY_BUFFER_RECT)
    ERR_STR(CL_COMMAND_USER)
    ERR_STR(CL_COMMAND_BARRIER)
    ERR_STR(CL_COMMAND_MIGRATE_MEM_OBJECTS)
    ERR_STR(CL_COMMAND_FILL_BUFFER)
    ERR_STR(CL_COMMAND_FILL_IMAGE)
#if defined(CL_COMMAND_SVM_FREE)
    ERR_STR(CL_COMMAND_SVM_FREE)
#endif
#if defined(CL_COMMAND_SVM_MEMCPY)
    ERR_STR(CL_COMMAND_SVM_MEMCPY)
#endif
#if defined(CL_COMMAND_SVM_MEMFILL)
    ERR_STR(CL_COMMAND_SVM_MEMFILL)
#endif
#if defined(CL_COMMAND_SVM_MAP)
    ERR_STR(CL_COMMAND_SVM_MAP)
#endif
#if defined(CL_COMMAND_SVM_UNMAP)
    ERR_STR(CL_COMMAND_SVM_UNMAP)
#endif
    default:
      return "Unknown cl_command_type";
  }
}

}  // namespace opencl
}  // namespace hal
}  // namespace tile
}  // namespace vertexai
